"""
Console utilities that add automatic color styling to every prompt message.
This module monkey-patches `click.echo` and the builtin `print` so that
messages across the CLI consistently highlight success/failure states and
important contextual details (paths, branch names, etc.).

Install scripts are excluded because they do not import this module.
"""
from __future__ import annotations

import builtins
import re
import sys
from typing import Any

import click

RESET_CODE = click.style("", reset=True)

_COLOR_CACHE: dict[str, str] = {}


def _color_code(name: str | None) -> str:
    if not name:
        return ""
    if name not in _COLOR_CACHE:
        _COLOR_CACHE[name] = click.style("", fg=name, reset=False)
    return _COLOR_CACHE[name]


SUCCESS_KEYWORDS = ("success", "成功", "已完成", "done", "完成", "✓")
WARNING_KEYWORDS = ("warning", "warn", "注意", "警告", "⚠")
ERROR_KEYWORDS = ("error", "failed", "failure", "失败", "错误", "异常", "✗")

COLON_PATTERN = re.compile(r"([：:]\s*)([^：:\n]+)")
EQUAL_PATTERN = re.compile(r"([A-Za-z0-9_.-]+\s*=\s*)([^,\s]+)")
PATH_PATTERN = re.compile(r"(/[\w.\-~/]+)")
SHA_PATTERN = re.compile(r"\b[0-9a-f]{7,40}\b")
BACKTICK_PATTERN = re.compile(r"`([^`\n]+)`")
BRACKET_PATTERN = re.compile(r"\[([^\]\n]+)\]")


def _style_token(token: str, *, fg: str | None = None, bold: bool = False, base_code: str = "") -> str:
    styled = click.style(token, fg=fg, bold=bold)
    return f"{styled}{base_code}" if base_code else styled


def _highlight_segments(text: str, base_code: str) -> str:
    text = text.replace("✓", _style_token("✓", fg="bright_green", bold=True, base_code=base_code))
    text = text.replace("✗", _style_token("✗", fg="red", bold=True, base_code=base_code))
    text = text.replace("⚠", _style_token("⚠", fg="yellow", bold=True, base_code=base_code))

    text = BACKTICK_PATTERN.sub(lambda m: _style_token(m.group(0), fg="bright_white", bold=True, base_code=base_code), text)
    text = BRACKET_PATTERN.sub(lambda m: f"[{_style_token(m.group(1), fg='bright_white', bold=True, base_code=base_code)}]", text)
    text = PATH_PATTERN.sub(lambda m: _style_token(m.group(0), fg="bright_white", bold=True, base_code=base_code), text)
    text = SHA_PATTERN.sub(lambda m: _style_token(m.group(0), fg="bright_white", bold=True, base_code=base_code), text)
    text = EQUAL_PATTERN.sub(lambda m: f"{m.group(1)}{_style_token(m.group(2), bold=True, base_code=base_code)}", text)
    text = COLON_PATTERN.sub(lambda m: f"{m.group(1)}{_style_token(m.group(2), bold=True, base_code=base_code)}", text)
    return text


def _detect_severity(text: str, err: bool) -> str:
    lowered = text.lower()
    if err:
        return "error"
    if any(keyword in lowered for keyword in ERROR_KEYWORDS):
        return "error"
    if any(keyword in lowered for keyword in WARNING_KEYWORDS):
        return "warning"
    if any(keyword in lowered for keyword in SUCCESS_KEYWORDS):
        return "success"
    return "info"


SEVERITY_COLORS = {
    "error": "red",
    "warning": "yellow",
    "success": "bright_green",
    "info": "bright_cyan",
}


def _prepare_value(value: Any, *, err: bool) -> str:
    if value is None:
        return ""
    if isinstance(value, (bytes, bytearray)):
        text = value.decode("utf-8", errors="ignore")
    else:
        text = str(value)
    if not text.strip():
        return text

    severity = _detect_severity(text, err)
    base_color = SEVERITY_COLORS.get(severity)
    base_code = _color_code(base_color)

    text = _highlight_segments(text, base_code)

    if base_code:
        text = f"{base_code}{text}{RESET_CODE}"
    return text


_original_click_echo = click.echo
_original_print = builtins.print
_PATCHED = False


def _styled_echo(message: Any = None, file=None, nl: bool = True, err: bool = False, color=None) -> None:
    target = file or (sys.stderr if err else sys.stdout)
    styled = _prepare_value(message, err=target is sys.stderr)
    _original_click_echo(styled, file=file, nl=nl, err=err, color=color)


def _styled_print(*objects: Any, sep: str = " ", end: str = "\n", file=None, flush: bool = False) -> None:
    target = file or sys.stdout
    if not objects:
        _original_print(*objects, sep=sep, end=end, file=file, flush=flush)
        return
    err = target is sys.stderr
    styled_objects = [_prepare_value(obj, err=err) for obj in objects]
    _original_print(*styled_objects, sep=sep, end=end, file=file, flush=flush)


def enable():
    global _PATCHED
    if _PATCHED:
        return
    click.echo = _styled_echo  # type: ignore[assignment]
    builtins.print = _styled_print  # type: ignore[assignment]
    _PATCHED = True


# Enable styling automatically when the module is imported.
enable()


